/*
    OpenLib
    Copyright (C) 2011  Michael Gukov

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/



jsun.dom = function(param, data) {
    if (!param) return jsun.dom;
    if (typeof param == "object")
        return jsun.dom.from_json(param)

    var work = {};
    work['#'] = jsun.dom.by_id;
    work['+'] = jsun.dom.create_elem;
    work['!'] = jsun.dom.eval;

    return work[param[0]].call(jsun.dom, param.substr(1));
};

jsun.dom.element = jsun.core.object.extend({
    owner:  null,
    events: null,
    construct: function(owner){
        this.owner.v = owner;
        this.events.v = [];
    },
    event: function(event) {
        for (var name in event) {
            if (! this.events.v[name]) {
                this.events.v[name] = [];
                var events = this.events.v[name];
                var element = this.owner.v;

                //element[name].addEventListener(name, event[name]);

                element[name] = function() {
                    for (var i in events)
                        events[i].apply(element, arguments);
                    return false;
                };
            }
            this.events.v[name].push(event[name]);
        }
    },
    elem: function() {
        return this.owner.v;
    }
});

jsun.dom.element_list = jsun.core.object.extend({
    elements: null,
    construct: function(elements) {
        this.elements.v = elements || [];
    },
    event: function(event) {
        for (var i in this.elements.v){
            var e = this.elements.v[i];
            jsun.dom.mix(e).event(event);
        }
    },
    mix: function() {
        for (var i in this.elements.v){
            var e = this.elements.v[i];
            jsun.dom.mix(e);
        }
        return e.jsun;
    },
    array: function() {
        return this.elements.v;
    },
    at: function(index) {
        return this.elements.v[index];
    },
    count: function() {
        return this.elements.v.length;
    },
    remove: function() {
        for (var i in this.elements.v){
            var e = this.elements.v[i];
            e.parentNode.removeChild(e);
        }
    },
    foreach: function(alg){
        for (var i in this.elements.v){
            alg(this.elements.v[i]);
        }
    }
});

jsun.dom.mix = function(e){
    // debug
    if (!e) alert("Null element jsun.dom.mix(e)");

    if (! e.jsun) e.jsun = new this.element(e);
    return e.jsun;
};

jsun.dom.by_id = function(id, doc){
    doc = doc || this.document;
    var e = doc.getElementById(id);
    if (e) this.mix(e);
    return e;
};

jsun.dom.list_by_id = function(arr){
    var elem = { };
    for (var i in arr){
        elem[arr[i]] = this.by_id(arr[i]);
    }
    return this.create_list(elem);
};

jsun.dom.create_list = function(elements){
    return new this.element_list(elements);
};

jsun.dom.from_json = function(node, doc){
    doc = doc || this.document;
    if (node.text !== undefined){
        return doc.createTextNode(node.text);
    }

    var root = doc.createElement(node.tag);
    this.mix(root);

    for (var i in node.attr){
        root.setAttribute(i, node.attr[i]);
    }

    for (i in node.body){
        root.appendChild(this.from_json(node.body[i], doc));
    }

    for (i in node.evn){
        var evn = { };
        evn[i] = node.evn[i];
        root.jsun.event(evn);
    }
    return root;
};

jsun.dom.create_elem = function(name) {
    var e = this.document.createElement(name);
    this.mix(e);
    return e;
}
jsun.dom.eval = function(src) {
    return eval("(" + src + ")");
}
jsun.dom.document = document;